/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.features.mocking;

import picounit.Should;
import picounit.mocker.Action;
import picounit.mocker.ArrayStubConsequenceMatcher;
import picounit.mocker.BaseStubConsequenceMatcher;
import picounit.mocker.BooleanArrayAction;
import picounit.mocker.BooleanArrayStubConsequenceMatcher;
import picounit.mocker.ByteArrayAction;
import picounit.mocker.ByteArrayStubConsequenceMatcher;
import picounit.mocker.CharArrayAction;
import picounit.mocker.CharArrayStubConsequenceMatcher;
import picounit.mocker.DoubleArrayAction;
import picounit.mocker.DoubleArrayStubConsequenceMatcher;
import picounit.mocker.FloatArrayAction;
import picounit.mocker.FloatArrayStubConsequenceMatcher;
import picounit.mocker.IntArrayAction;
import picounit.mocker.IntArrayStubConsequenceMatcher;
import picounit.mocker.LongArrayAction;
import picounit.mocker.LongArrayStubConsequenceMatcher;
import picounit.mocker.OccurencesMatcher;
import picounit.mocker.PostConsequenceMatcher;
import picounit.mocker.ShortArrayAction;
import picounit.mocker.ShortArrayStubConsequenceMatcher;
import picounit.mocker.StringArrayAction;
import picounit.mocker.StringArrayStubConsequenceMatcher;
import picounit.mocker.VoidAction;

@SuppressWarnings("unchecked")
class ArrayStubber implements BaseStubConsequenceMatcher,
	BooleanArrayStubConsequenceMatcher, ByteArrayStubConsequenceMatcher,
	CharArrayStubConsequenceMatcher, DoubleArrayStubConsequenceMatcher,
	FloatArrayStubConsequenceMatcher, IntArrayStubConsequenceMatcher,
	LongArrayStubConsequenceMatcher, ShortArrayStubConsequenceMatcher,
	StringArrayStubConsequenceMatcher, ArrayStubConsequenceMatcher {

	private final CombinedArrayConsequenceMatcher combinedArrayConsequenceMatcher;
	private final Should should;

	public ArrayStubber(CombinedArrayConsequenceMatcher combinedArrayConsequenceMatcher,
		Should should) {

		this.combinedArrayConsequenceMatcher = combinedArrayConsequenceMatcher;
		this.should = should;
	}

	public void thenRaise(Throwable toRaise) {
		optionally(combinedArrayConsequenceMatcher.andRaise(toRaise));
	}

	public void thenReturn(boolean ... returnValue) {
		optionally(combinedArrayConsequenceMatcher.andReturn(returnValue));
	}

	public void thenReturn(byte ... returnValue) {
		optionally(combinedArrayConsequenceMatcher.andReturn(returnValue));
	}

	public void thenReturn(char ... returnValue) {
		optionally(combinedArrayConsequenceMatcher.andReturn(returnValue));
	}

	public void thenReturn(double ... returnValue) {
		optionally(combinedArrayConsequenceMatcher.andReturn(returnValue));
	}

	public void thenReturn(float ... returnValue) {
		optionally(combinedArrayConsequenceMatcher.andReturn(returnValue));
	}

	public void thenReturn(int ... returnValue) {
		optionally(combinedArrayConsequenceMatcher.andReturn(returnValue));
	}

	public void thenReturn(long ... returnValue) {
		optionally(combinedArrayConsequenceMatcher.andReturn(returnValue));
	}

	public void thenReturn(short ... returnValue) {
		optionally(combinedArrayConsequenceMatcher.andReturn(returnValue));
	}

	public void thenReturn(String ... returnValue) {
		optionally(combinedArrayConsequenceMatcher.andReturn(returnValue));
	}

	public void thenReturn(Object[] returnValue) {
		optionally(combinedArrayConsequenceMatcher.andReturn(returnValue));
	}
	
	public void thenPerform(BooleanArrayAction action) {
		optionally(combinedArrayConsequenceMatcher.andPerform(action));
	}
	
	public void thenPerform(ByteArrayAction action) {
		optionally(combinedArrayConsequenceMatcher.andPerform(action));
	}
	
	public void thenPerform(CharArrayAction action) {
		optionally(combinedArrayConsequenceMatcher.andPerform(action));
	}
	
	public void thenPerform(DoubleArrayAction action) {
		optionally(combinedArrayConsequenceMatcher.andPerform(action));
	}
	
	public void thenPerform(FloatArrayAction action) {
		optionally(combinedArrayConsequenceMatcher.andPerform(action));
	}
	
	public void thenPerform(IntArrayAction action) {
		optionally(combinedArrayConsequenceMatcher.andPerform(action));
	}

	public void thenPerform(LongArrayAction action) {
		optionally(combinedArrayConsequenceMatcher.andPerform(action));
	}

	public void thenPerform(ShortArrayAction action) {
		optionally(combinedArrayConsequenceMatcher.andPerform(action));
	}

	public void thenPerform(StringArrayAction action) {
		optionally(combinedArrayConsequenceMatcher.andPerform(action));
	}

	public void thenPerform(Action action) {
		optionally(combinedArrayConsequenceMatcher.andPerform(action));
	}

	public void perform(VoidAction voidAction) {
		optionally(should.perform(voidAction));
	}

	public void raise(Throwable throwable) {
		optionally(should.raise(throwable));
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// Implementation
	///////////////////////////////////////////////////////////////////////////////////////////////

	private PostConsequenceMatcher optionally(OccurencesMatcher occurencesMatcher) {
		return occurencesMatcher.optional();
	}
}
